<!--
 * @Author: WangShuai 1830773767@qq.com
 * @Date: 2025-06-16 15:22:11
 * @LastEditors: WangShuai 1830773767@qq.com
 * @LastEditTime: 2025-06-17 22:55:23
 * @FilePath: \vue3_admin_template\project\src\components\PublicMap\MapEchart\mapAndEchart.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%A

-->
<template>
  <!-- 聚合图 -->
  <el-menu-item index="3" @click="getData" style="margin: 0 0 0 20px">
    查询
  </el-menu-item>
</template>

<script setup lang="ts">
import mapboxgl from 'mapbox-gl'
import 'mapbox-gl/dist/mapbox-gl.css'
import { onMounted, ref } from 'vue'
import * as echarts from 'echarts'
import useMapStore from '@/store/modules/map'
import type { Feature, FeatureCollection } from '../type/type'
let map: any = null
let feature = ref()
//定义一个空的popup
let popup: any = null
let myChart: any = null
let currentFeatureName: any = null
//定义高亮数据
let hight_data: FeatureCollection = {
  type: 'FeatureCollection',
  features: [],
}
//获取数据
const getData = async () => {
  const response = await fetch('/public/aggregation/wuhan_people.json')
  const result = await response.json()
  feature.value = result
}
//渲染图层
const renderLayer = () => {
  map.addSource('fill_Source', {
    type: 'geojson',
    data: feature.value,
  })
  map.addLayer({
    id: 'fill_Layer',
    source: 'fill_Source',
    // type: 'fill',
    // paint: {
    //   'fill-color': 'pink',
    //   'fill-opacity': 0.8,
    //   'fill-outline-color': 'yellow', //不能设width
    // },
    type: 'fill-extrusion',
    paint: {
      'fill-extrusion-height': ['max', 5, ['/', ['get', 'people'], 500]], // 最小高度为5,
      // 使用 interpolate 表达式，基于 people/1000 的结果映射颜色
      'fill-extrusion-color': [
        'interpolate',
        ['linear'],
        ['/', ['get', 'people'], 10000], // 计算 people/1000
        30,
        'green', // 当 people/10000 = 30 时为绿色
        50,
        'yellow', // 当 people/10000 = 50 时为黄色
        70,
        '#652e80', // 当 people/10000 = 70 时为紫色
        90,
        'red', // 当 people/10000 = 90 时为红色
        100,
        '#409EFF', // 当 people/10000 = 100 时为靛色
      ],

      'fill-extrusion-opacity': 0.7,
      'fill-extrusion-base': 0,
      'fill-extrusion-opacity-transition': {
        duration: 500,
        delay: 0,
      },
      'fill-extrusion-color-transition': {
        duration: 500,
        delay: 0,
      },
    },
  })
  //定义高亮数据源
  map.addSource('hight_source', {
    type: 'geojson',
    data: hight_data,
  })
  //定义高亮图层
  map.addLayer({
    id: 'hight_layer',
    source: 'hight_source',
    type: 'fill-extrusion',
    paint: {
      'fill-extrusion-color': '#1C69FE',
      // 高亮层高度 = 基础层高度 * 1.2 + 50（确保至少比基础层高50个单位）
      'fill-extrusion-height': [
        '+',
        50,
        ['*', ['max', 5, ['/', ['get', 'people'], 500]], 1.2],
      ],
      'fill-extrusion-opacity': 0.9,
    },
  })
  //给地图绑定事件
  map.on('mouseover', 'fill_Layer', () => {
    //设置鼠标样式为手型
    map.getCanvas().style.cursor = 'pointer'
  })
  map.on('mouseout', 'fill_Layer', () => {
    //设置鼠标样式为默认
    map.getCanvas().style.cursor = 'default'
    //鼠标离开时数据源为空
    let hight_source = map.getSource('hight_source')
    hight_data.features = []
    hight_source.setData(hight_data)

    //清除popup
    if (popup) {
      popup.remove()
      popup = null
      myChart = null
      currentFeatureName = null
    }
  })
  map.on('mousemove', 'fill_Layer', (evt: any) => {
    if (evt.features && evt.features.length > 0) {
      // 将单个要素包装在 FeatureCollection 中
      let hight_source = map.getSource('hight_source') as mapboxgl.GeoJSONSource
      const feature = evt.features[0] as Feature
      hight_data.features.push(feature)
      //设置数据源
      hight_source.setData(evt.features[0])
    }
    renderPopupEchart(evt)
  })
}

//渲染PopupEchart
const renderPopupEchart = (evt: any) => {
  let { lngLat } = evt
  let { name, people } = evt.features[0].properties
  console.log('object', evt, evt.features[0])
  const numPeople = parseFloat(people)
  if (currentFeatureName == name) {
    // 鼠标在同一 feature 中，仅更新位置和数据
    popup.setLngLat(lngLat)
    if (myChart) {
      myChart.setOption(
        {
          series: [
            {
              data: [numPeople],
            },
          ],
        },
        true,
      )
    }
  } else {
    // 移动到另外一个 feature 中
    if (!popup) {
      popup = new mapboxgl.Popup({
        closeButton: false,
        //初始描点经纬度
        lngLat,
        //popup 标题
        //Popup 内容
        html: `<span>所在地区:${name}</span></br>
                               <span>总人数${numPeople}</span>
                                <div id="echart-container" style="width: 250px; height: 200px;"></div> `,
      })
        .setLngLat(lngLat)
        .addTo(map)
      initEchart(numPeople)
    } else {
      popup.setLngLat(lngLat)
      const content = `<span>所在地区:${name}</span></br>
                                             <span>总人数${numPeople}</span>
                                             <div id="echart-container" style="width: 250px; height: 200px;"></div>`
      popup.setHTML(content)
      // 确保 popup 已经添加到 DOM 中再初始化 ECharts
      initEchart(numPeople)
    }
    currentFeatureName = name
  }
}
////初始化Echart函数
const initEchart = (numPeople: number) => {
  // 确保 popup 已经添加到 DOM 中再初始化 ECharts
  setTimeout(() => {
    const echartContainer = document.getElementById('echart-container')
    // 初始化 ECharts 实例并设置图表配置
    if (echartContainer) {
      const myChart = echarts.init(echartContainer)
      const option = {
        grid: {
          left: '20%', // 增加左内边距，将图表向右移动
        },
        xAxis: {
          type: 'category',
          data: ['人口数量'],
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            // 自定义 y 轴数值显示，这里将数值转换为以万为单位
            formatter: function (value: any) {
              if (value >= 10000) {
                return (value / 10000).toFixed(1) + ' 万'
              } else {
                return value.toFixed(0)
              }
            },
          },
        },
        series: [
          {
            data: [numPeople],
            type: 'bar',
          },
        ],
      }
      myChart.setOption(option)
    }
  }, 200)
}
onMounted(async () => {
  map = useMapStore().map
  // 确保地图已加载完成
  await map.once('style.load')
  await getData() // 等待数据加载完成
  //渲染图层
  renderLayer()
})
</script>

<style lang="scss" scoped></style>
